﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Data;
using Microsoft.Practices.Prism.ViewModel;
using Schulz.ProControl.Common.Presentation.Command;
using Microsoft.Win32;
using System.Diagnostics;
using Controls.WiiMote;

namespace WiiLuvScumm
{
    public class ViewModel : NotificationObject
    {
        public ViewModel()
        {
            Games = GameManager.LoadGames();
            WiiMoteManager.Init();
        }

        #region Properties

        #region WiiMoteManager

        public WiiMoteManager WiiMoteManager
        {
            get { return wiiMoteManager ?? (wiiMoteManager = new WiiMoteManager()); }
            set
            {
                if (wiiMoteManager != value)
                {
                    wiiMoteManager = value;
                    RaisePropertyChanged(() => Games);
                }
            }
        }

        private WiiMoteManager wiiMoteManager;

        #endregion

        #region Games

        public ObservableCollection<Game> Games
        {
            get { return games ?? (games = new ObservableCollection<Game>()); }
            set
            {
                if (games != value)
                {
                    games = value;
                    RaisePropertyChanged(() => Games);
                }
            }
        }

        private ObservableCollection<Game> games;

        #endregion

        #region GameManager

        public GameManager GameManager
        {
            get { return gameManager ?? (gameManager = new GameManager()); }
            set
            {
                if (gameManager != value)
                {
                    gameManager = value;
                    RaisePropertyChanged(() => GameManager);
                }
            }
        }

        private GameManager gameManager;

        #endregion

        #region AddGameDialogVisibility

        public Visibility AddGameDialogVisibility
        {
            get { return addGameDialogVisibility; }
            set
            {
                if (addGameDialogVisibility != value)
                {
                    addGameDialogVisibility = value;
                    RaisePropertyChanged(() => AddGameDialogVisibility);
                }
            }
        }

        private Visibility addGameDialogVisibility = Visibility.Collapsed;

        #endregion

        #region SettingsDialogVisibility

        public Visibility SettingsDialogVisibility
        {
            get { return settingsDialogVisibility; }
            set
            {
                if (settingsDialogVisibility != value)
                {
                    settingsDialogVisibility = value;
                    RaisePropertyChanged(() => SettingsDialogVisibility);
                }
            }
        }

        private Visibility settingsDialogVisibility = Visibility.Collapsed;

        #endregion

        #endregion


        #region Commands

        #region CloseAddGameDialogCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand CloseAddGameDialogCommand
        {
            get { return new GenericCommand(this.ExecuteCloseAddGameDialog, this.CanCloseAddGameDialog); }
        }

        /// <summary>
        /// Determines if the CloseAddGameDialogCommand can be executed.
        /// </summary>
        private bool CanCloseAddGameDialog(object obj)
        {
            return true;
        }

        /// <summary>
        /// Executes when the CloseAddGameDialogCommand is called.
        /// </summary>
        private void ExecuteCloseAddGameDialog(object obj)
        {
            AddGameDialogVisibility = Visibility.Collapsed;
        }

        #endregion

        #region AddGameCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand AddGameCommand
        {
            get { return new GenericCommand(this.ExecuteAddGame); }
        }

        /// <summary>
        /// Executes when the AddGameCommand is called.
        /// </summary>
        private void ExecuteAddGame(object obj)
        {
            AddGameDialogVisibility = Visibility.Visible;
        }

        #endregion


        #region StartGameCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand StartGameCommand
        {
            get { return new GenericCommand(this.ExecuteStartGame, this.CanStartGame); }
        }

        private bool CanStartGame(object obj)
        {
            return obj is Game && !String.IsNullOrEmpty(GameManager.Settings.PathToScummVMexe);
        }

        /// <summary>
        /// Executes when the AddGameCommand is called.
        /// </summary>
        private void ExecuteStartGame(object obj)
        {
            var game = obj as Game;
            var startInfo = new ProcessStartInfo
                                {
                                    FileName = GameManager.Settings.PathToScummVMexe,
                                    Arguments = String.Format("-f -p \"{0}\" {1}", game.GameFolder, game.GameExe.Split('.')[0]),
                                    UseShellExecute = false
                                };

            Process.Start(startInfo);
        }

        #endregion
        

        #endregion

        #region AddGameDialog

        #region Properties

        #region SelectedGameTemplate

        public Game SelectedGameTemplate
        {
            get { return selectedGameTemplate; }
            set
            {
                if (selectedGameTemplate != value)
                {
                    selectedGameTemplate = value;
                    RaisePropertyChanged(() => SelectedGameTemplate);
                }
            }
        }

        private Game selectedGameTemplate;

        #endregion


        #endregion

        #region Commands

        #region DialogAddGameCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand DialogAddGameCommand
        {
            get { return new GenericCommand(this.ExecuteDialogAddGame, this.CanDialogAddGame); }
        }

        /// <summary>
        /// Determines if the DialogAddGameCommand can be executed.
        /// </summary>
        private bool CanDialogAddGame(object obj)
        {
            return SelectedGameTemplate != null && !String.IsNullOrEmpty(selectedGameTemplate.GameFolder);
        }

        /// <summary>
        /// Executes when the DialogAddGameCommand is called.
        /// </summary>
        private void ExecuteDialogAddGame(object obj)
        {
            Games.Add(SelectedGameTemplate);
            GameManager.SaveGames(Games);
        }

        #endregion

        #region DialogRemoveGameCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand DialogRemoveGameCommand
        {
            get { return new GenericCommand(this.ExecuteDialogRemoveGame, this.CanDialogRemoveGame); }
        }

        /// <summary>
        /// Determines if the DialogRemoveGameCommand can be executed.
        /// </summary>
        private bool CanDialogRemoveGame(object obj)
        {
            return obj is Game;
        }

        /// <summary>
        /// Executes when the DialogRemoveGameCommand is called.
        /// </summary>
        private void ExecuteDialogRemoveGame(object obj)
        {
            if (Games.Contains(obj as Game))
            {
                Games.Remove(obj as Game);
                GameManager.SaveGames(Games);
            }
        }

        #endregion

        #region ChooseGameLocationCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand ChooseGameLocationCommand
        {
            get { return new GenericCommand(this.ExecuteChooseGameLocation); }
        }


        /// <summary>
        /// Executes when the DialogRemoveGameCommand is called.
        /// </summary>
        private void ExecuteChooseGameLocation(object obj)
        {
            //
            //  look for glove pie
            // 
            // Displays an OpenFileDialog so the user can select a Cursor.
            var openFileDialog = new OpenFileDialog();
            var game = obj as Game;
            var gameName = game.GameExe.Split('.')[0];
            openFileDialog.Filter = gameName + "|" + (obj as Game).GameExe;
               ;
            openFileDialog.Title = "Select " + (obj as Game).GameExe;

            // Show the Dialog.
            var result = openFileDialog.ShowDialog();
            if (result == true)
            {
                // Assign the cursor in the Stream to the Form's Cursor property.
                game.GameFolder = System.IO.Path.GetDirectoryName(openFileDialog.FileName);                
            }
        }

        #endregion

        
        #endregion

        #endregion

        #region General Settings Dialog

        #region Properties

        

        #endregion

        #region Commands

        #region ChooseGlovePiePathCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand ChooseGlovePiePathCommand
        {
            get { return new GenericCommand(this.ExecuteChooseGlovePiePath); }
        }
              

        /// <summary>
        /// Executes when the ChooseGlovePiePathCommand is called.
        /// </summary>
        private void ExecuteChooseGlovePiePath(object obj)
        {
            //
            //  look for glove pie
            // 
        }

        #endregion

        #region ChooseScummVMPathCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand ChooseScummVMPathCommand
        {
            get { return new GenericCommand(this.ExecuteChooseScummVMPath); }
        }


        /// <summary>
        /// Executes when the ChooseGlovePiePathCommand is called.
        /// </summary>
        private void ExecuteChooseScummVMPath(object obj)
        {
            //
            //  look for glove pie
            // 
            // Displays an OpenFileDialog so the user can select a Cursor.
            var openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "ScummVm|scummvm.exe";
            openFileDialog.Title = "Select ScummVM.exe";

            // Show the Dialog.
            // If the user clicked OK in the dialog and
            // a .CUR file was selected, open it.
            var result = openFileDialog.ShowDialog();
            if (result == true)
            {
                // Assign the cursor in the Stream to the Form's Cursor property.
                GameManager.Settings.PathToScummVMexe = openFileDialog.FileName;
                GameManager.SaveSettings();
                    
            }
        }

        #endregion


        #region ShowSettingsCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand ShowSettingsCommand
        {
            get { return new GenericCommand(this.ExecuteShowSettings); }
        }


        /// <summary>
        /// Executes when the ChooseGlovePiePathCommand is called.
        /// </summary>
        private void ExecuteShowSettings(object obj)
        {
            SettingsDialogVisibility = Visibility.Visible;
        }

        #endregion

        #region HideSettingsCommand

        /// <summary>
        ///
        /// </summary>
        public ICommand HideSettingsCommand
        {
            get { return new GenericCommand(this.ExecuteHideSettings); }
        }


        /// <summary>
        /// Executes when the ChooseGlovePiePathCommand is called.
        /// </summary>
        private void ExecuteHideSettings(object obj)
        {
            SettingsDialogVisibility = Visibility.Collapsed;
        }

        #endregion

        #endregion

        #endregion
    }
}
